package com.tomdd.message;

import com.tomdd.message.enums.MessageTypeEnum;
import com.tomdd.message.handler.MessageHandler;
import com.tomdd.message.model.Message;
import com.tomdd.message.model.OutMessage;
import lombok.Getter;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 消息路由规则
 *
 * @author zx
 * @date 2025年04月25日 13:56
 */
public class MessageRouterRule {

    private final MessageRouter routerBUilder;
    @Getter
    private boolean async = true;

    private MessageTypeEnum msgType;


    private List<MessageHandler> handlers = new ArrayList<>();

    //也可以扩展出消息拦截处理方式。

    public MessageRouterRule(MessageRouter routerBUilder) {
        this.routerBUilder = routerBUilder;
    }

    //使用建造者设计模式给属性赋值
    public MessageRouterRule async(boolean async) {
        this.async = async;
        return this;
    }

    public MessageRouterRule msgType(MessageTypeEnum msgType) {
        this.msgType = msgType;
        return this;
    }


    public MessageRouterRule handler(MessageHandler handler) {
        return handler(handler, (MessageHandler[]) null);
    }

    public MessageRouterRule handler(MessageHandler handler, MessageHandler... otherHandlers) {
        this.handlers.add(handler);
        if (otherHandlers != null && otherHandlers.length > 0) {
            for (MessageHandler messageHandler : otherHandlers) {
                this.handlers.add(messageHandler);
            }
        }
        return this;
    }

    /**
     * 规则结束，代表如果一个消息匹配该规则，那么它将不再会进入其他规则
     *
     * @return message router
     */
    public MessageRouter end() {
        //把当前路由规则添加到路由器里面的路由规则集合中。
        //this.routerBUilder.getRules().add(this);
        this.routerBUilder.getRules().put(this.msgType, this);

        return this.routerBUilder;
    }

    public Boolean test(Message message) {
        MessageTypeEnum messageType = message.getMessageType();
        return messageType != null && this.msgType == messageType;
    }

    public OutMessage service(Message message, Map<String, Object> context) {
        //处理消息前
        //处理消息后  需要提前组装拦截器,和消息处理器那样的操作。

        // 交给handler处理
        OutMessage res = null;

        for (MessageHandler handler : this.handlers) {
            // 返回最后handler的结果
            if (handler == null) {
                continue;
            }
            res = handler.handler(message);
        }
        return res;
    }
}
